﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NHINDirect
{
    public struct CharReader
    {
        string m_source;
        int m_position;
        int m_maxPosition;
        
        public CharReader(StringSegment source)
        {
            this.m_source = source.Source;
            this.m_position = source.StartIndex;
            this.m_maxPosition = this.m_position + source.Length;
        }

        public CharReader(string source)
        {
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException();
            }

            this.m_source = source;
            this.m_position = 0;
            this.m_maxPosition = this.m_position + source.Length;
        }
        
        public string Source
        {
            get
            {
                return this.m_source;
            }
        }

        public int Position
        {
            get
            {
                return this.m_position - 1;
            }
        }
        
        public bool IsDone
        {
            get
            {
                return (this.m_position == this.m_maxPosition);
            }
        }
        
        public char Read()
        {
            if (this.IsDone)
            {
                return char.MinValue;
            }

            return this.m_source[this.m_position++];
        }
        
        public bool ReadTo(char chTo)
        {
            char ch;
            while ((ch = this.Read()) != char.MinValue)
            {
                if (ch == chTo)
                {
                    return true;
                }
            }
            
            return false;
        }
        
        public char Peek()
        {
            int next = this.m_position + 1;
            if (next >= this.m_maxPosition)
            {
                return char.MinValue;
            }
            
            return this.m_source[next];
        }
        
        public bool IsNext(char ch)
        {
            return (this.Peek() == ch);
        }
        
        public char PeekPrev()
        {
            int prev = this.m_position - 1;
            if (prev < 0)
            {
                return char.MinValue;
            }
            
            return this.m_source[prev];
        }
        
        public bool IsPrev(char ch)
        {
            return (this.PeekPrev() == ch);
        }
    }
}
